// 定义一个副作用函数桶
const bucket = new WeakMap(); // [state1 ---> Map[name-->Set(fn1,fn2...), age-->Set(fn...)], state2 ---> Map]

// 定义一个全局变量，保存当前正在执行的副作用函数
let activeEffect = null;

function isObject(value) {
  return typeof value === "object" && value !== null;
}
/**
 * 收集依赖
 */
function track(target, key) {
  if (!activeEffect) return;
  let depMap = bucket.get(target)
  if (!depMap) {
    depMap = new Map();
    bucket.set(target, depMap);
  }
  let depSet = depMap.get(key)
  if(!depSet) {
    depSet = new Set()
    depMap.set(key, depSet)
  }
  // 只有activeEffect有值时，才添加到桶中
  // depSet 依旧是Set结构，同样先天就可以去重
  depSet.add(activeEffect);
}
/**
 * 触发更新
 */
function trigger(target, key) {
  // 调用副作用函数
  let depMap = bucket.get(target);
  if (!depMap) return

  let depSet = depMap.get(key)
  depSet && depSet.forEach((fn) => fn());

}
function reactive(data) {
  if (!isObject) return;

  return new Proxy(data, {
    get(target, key) {
      // 在get操作时，收集依赖
      track(target, key);
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      // 在set操作时，触发副作用函数重新执行
      trigger(target,key)
      return true;
    },
  });
}
/**
 * 注册副作用函数
 * @param {*} fn
 */
function effect(fn) {
  if (typeof fn !== "function") return;
  // 记录正在执行的副作用函数
  activeEffect = fn;
  // 调用
  fn();
  // 重置全局变量
  activeEffect = null;
}